/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lab5cyclebuffer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * @author Daryna_Ragimova
 */
public class Buffer {

    private int[] buf;
    private int size;
    private boolean empty = true;
    private boolean full = false;
    private int start = 0;
    private int end = -1;
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition conditionFull = lock.newCondition();
    private final Condition conditionEmpty = lock.newCondition();
    
    public Buffer(int N) {
        buf = new int[N];
        this.size = N;
    }

    
    public void put(Integer i) throws InterruptedException {
        lock.lock();
        try {
            while (full) {
                if (start == (end + 1) % size) {
                    System.out.println("Try to put " + i);
                    conditionFull.await();
                }
            }
            end = (end + 1) % size;
            System.out.println("Put " + i);
            buf[end] = i;
            empty = false;
            if ((end + 1) % size == start) {
                full = true;
            }
            conditionEmpty.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public Integer get() throws InterruptedException {
        lock.lock();
        try {
            while (empty) {
                if (start == (end + 1) % size) {
                    System.out.println("Try to get ");
                    conditionEmpty.await();
                }
            }
            int t = buf[start];
            buf[start] = 0;
            start = (start + 1) % size;
            full = false;
            if ((end + 1) % size == start) {
                empty = true;
            }
            conditionFull.signalAll();
            return t;
        } finally {
            lock.unlock();
        }
        
    }
}
